# Object pool

# definition ----------------------------------------
# Object pool class
class ObjectPool:
    allocated = []
    pool = []

    def __init__(self, objectFactory, size):
        self.objectFactory = objectFactory
        i = 0
        while i < size:
            self.pool.append(self.objectFactory.createObj())
            i += 1
    
    def allocate(self):
        if self.size() != 0:
            obj = self.pool.pop(0)
            self.allocated.append( obj )
            return obj
        else:
            raise PoolException("Pool is all allocated")

    def release(self, obj):
        if obj in self.allocated:
            self.pool.append( obj )
            self.allocated.remove( obj )
                  
    def size(self):
        return len(self.pool)

# Object factory class
class ObjectFactory:

    def createObj(self):
        return Cat()
        
# Cat class
class Cat:

    def doSomething(self):
        print "Miauuuuu"

    def __str__(self):
        return "I am a cat."

# Exception class
class PoolException(Exception):

    def __init__(self, value):
        self.value = value

    def __str__(self):
        return repr(self.value)
    
# implementation ----------------------------------------

objFact = ObjectFactory()
objPool = ObjectPool(objFact, 5)
print "Pool size: " + str(objPool.size())
obj1 = objPool.allocate()
print obj1
print "Pool size: " + str(objPool.size())
obj2 = objPool.allocate()
print obj2
print "Pool size: " + str(objPool.size())
obj3 = objPool.allocate()
print obj3
print "Pool size: " + str(objPool.size())
obj4 = objPool.allocate()
print obj4
print "Pool size: " + str(objPool.size())
obj5 = objPool.allocate()
print obj5
print "Pool size: " + str(objPool.size())
objPool.release(obj1)
print "Pool size: " + str(objPool.size())
objPool.release(obj2)
print "Pool size: " + str(objPool.size())
objPool.release(obj3)
print "Pool size: " + str(objPool.size())
objPool.release(obj4)
print "Pool size: " + str(objPool.size())
objPool.release(obj5)
print "Pool size: " + str(objPool.size())
randomCat = Cat()
objPool.release(randomCat) #do nothing, this cat was never allocated
print "Pool size: " + str(objPool.size())
